#ifndef _PARTITION_H 
#define _PARTITION_H

#include "Geometry.h"
#include "Excitation.h"

class Partition
{
public:
	Partition(){};
	~Partition(){};
};

class MoM_Partition:public Partition
{
public:
	friend class MoM_Solver;
	MoM_Partition(MoM_Geometry *geo, PlaneWave* ex, real_data lX, real_data uX,
		real_data lY, real_data uY, real_data lZ, real_data uZ)
		:Geo(geo),Ex(ex),Low_X(lX),Up_X(uX),Low_Y(lY),Up_Y(uY),Low_Z(lZ),Up_Z(uZ)
	{
		ReadPartition();
		ExtendPartition();
// 		std::ofstream fout("part.dat");
// 		for (int i=0; i<PatchSet.size(); i++)
// 		{
// 			fout<<Patch[i]<<std::endl;
// 		}
// 		fout.close();
		GetIncomeV();
	};
	~MoM_Partition();
private:
	void ReadPartition();
	void AddPatch(int Patch_ID);
	void ExtendPartition();
	void GetIncomeV();
	int IGetN3(int Pat, int Node1, int Node2)
	{
		return Geo->Patch(Pat)[0]+Geo->Patch(Pat)[1]+Geo->Patch(Pat)[2]-Node1-Node2;
	};
private:
	std::vector<int> Edge, Patch;									// Partition's information
	std::vector<int> OutEdge;
	std::set<int> EdgeSet, PatchSet, BoundarySet;
	int Patch_Num, Edge_Num;

	blitz::Array<dComplex, 1> Pre;									// Precondition Vector

	blitz::Array<dComplex, 2> Z, OutEdgeZ;							// Impedance Matrix

	blitz::Array<dComplex, 1> V, IncomeV;							// Excitation Vector

	blitz::Array<dComplex, 1> I;									// Currents' coefficients

	MoM_Geometry *Geo;												// Father Geometry

	const PlaneWave* Ex;											// Incident Wave

	const real_data Low_X, Low_Y, Low_Z, Up_X, Up_Y, Up_Z;			// Division Rule
};

#endif